/*
Copyright 2010 Iain Surgey.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#define	LUMP_ENTITIES		0
#define	LUMP_PLANES			1
#define	LUMP_VERTEXES		2
#define	LUMP_VISIBILITY		3
#define	LUMP_NODES			4
#define	LUMP_TEXINFO		5
#define	LUMP_FACES			6
#define	LUMP_LIGHTING		7
#define	LUMP_LEAFS			8
#define	LUMP_LEAFFACES		9
#define	LUMP_LEAFBRUSHES	10
#define	LUMP_EDGES			11
#define	LUMP_SURFEDGES		12
#define	LUMP_MODELS			13
#define	LUMP_BRUSHES		14
#define	LUMP_BRUSHSIDES		15
#define	LUMP_POP			16
#define	LUMP_AREAS			17
#define	LUMP_AREAPORTALS	18
#define LUMP_COLLIDE		19
#define	HEADER_LUMPS		20

#define IT_SKIN 	0
#define IT_SPRITE 	1
#define IT_WALL 	2
#define IT_PIC		3
#define IT_SKY		4

#define	MAXLIGHTMAPS	4
#define	MIPLEVELS	4

#define	CONTENTS_NODE	-1
#define	CONTENTS_SOLID	1


struct
{	
//
// volume occupied by the model graphics
//		
	float		mins[3], maxs[3];
	
	int			numplanes;
	mplane_t	*planes;
	
	int			numleafs;		// number of visible leafs, not counting 0
	mleaf_t		*leafs;

	int			numvertexes;
	mvertex_t	*vertexes;

	int			numedges;
	medge_t		*edges;

	int			numnodes;
	int			firstnode;
	mnode_t		*nodes;
	
	int			numtexinfo;
	mtexinfo_t	*texinfo;
	
	int			numsurfaces;
	msurface_t	*surfaces;
	
	int			numsurfedges;
	int			*surfedges;
	
	int			nummarksurfaces;
	msurface_t	**marksurfaces;
	
	dvis_t		*vis;
	
	byte		*lightdata;
} model_t;

struct
{
	int			numclusters;
	int			bitofs[8];	// bitofs[numclusters][2]
} dvis_t;

struct
{
	int				contents;			// OR of all brushes (not needed?)

	short			cluster;
	short			area;

	short			mins[3];			// for frustum culling
	short			maxs[3];

	ushort	firstleafface;
	ushort	numleaffaces;

	ushort	firstleafbrush;
	ushort	numleafbrushes;
} dleaf_t;

struct
{
	int			planenum;
	int			children[2];	// negative numbers are -(leafs+1), not nodes
	short		mins[3];		// for frustom culling
	short		maxs[3];
	ushort	firstface;
	ushort	numfaces;	// counting both sides
} dnode_t;


struct
{
// common with leaf
	int			contents;		// CONTENTS_NODE, to differentiate from leafs
	int			visframe;		// node needs to be traversed if current
	
	short		minmaxs[6];		// for bounding box culling

	mnode_t	*parent;

// node specific
	mplane_t	*plane;
	mnode_t	*children[2];	

	ushort		firstsurface;
	ushort		numsurfaces;
} mnode_t;

struct
{
// common with node
	int			contents;		// wil be something other than CONTENTS_NODE
	int			visframe;		// node needs to be traversed if current
	
	short		minmaxs[6];		// for bounding box culling
	
	mnode_t	*parent;
	
// leaf specific
	int			cluster;
	int			area;
	
	msurface_t	**firstmarksurface;
	int			nummarksurfaces;
	int			key;			// BSP sequence number for leaf's contents
} mleaf_t;

struct
{
	float	normal[3];
	float	dist;
	int		type;		// PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} dplane_t;

struct
{
	ushort	v[2];
	int	cachededgeoffset;
} medge_t;

struct
{
	float		vecs[2][4];
	float		mipadjust;
	image_t		*image;
	int			flags;
	int			numframes;
	mtexinfo_t	*next;		// animation chain
	byte		collide;
} mtexinfo_t;

struct
{
	//char    name[MAX_QPATH];        // game path, including extension
	byte     type;
	int             width, height;
	byte        transparent;    // true if any 255 pixels in image
	int             registration_sequence;  // 0 = free
	byte		*pixels[4];				// mip levels
} image_t;

image_t         r_notexture_mip;

struct
{
	float		vecs[2][4];		// [s/t][xyz offset]
	int			flags;			// miptex flags + overrides
	int			value;			// light emission, etc
	byte		texture[32];	// texture name
	int			nexttexinfo;	// for animations, -1 = end of chain
} texinfo_t;

struct
{
	short	planenum;
	short		side;

	int			firstedge;		// we must support > 64k edges
	short		numedges;	
	short		texinfo;

// lighting info
	byte		styles[MAXLIGHTMAPS];
	int			lightofs;		// start of [numstyles*surfsize] samples
} dface_t;


struct
{
	surfcache_t      *next;
	surfcache_t      **owner;                // NULL is an empty chunk of memory
	int                                     lightadj[MAXLIGHTMAPS]; // checked for strobe flush
	int                                     dlight;
	int                                     size;           // including header
	int                        width;
	int                        height;         // DEBUG only needed for debug
	float                           mipscale;
	image_t							*image;
	byte                            data[4];        // width*height elements
} surfcache_t;


struct
{
	int			visframe;		// should be drawn when node is crossed

	int			dlightframe;
	int			dlightbits;

	mplane_t	*plane;
	int			flags;

	int			firstedge;	// look up in model->surfedges[], negative numbers
	int			numedges;	// are backwards edges
	
// surface generation data
	surfcache_t	*cachespots[MIPLEVELS];

	int		texturemins[2];
	int		extents[2];

	mtexinfo_t	*texinfo;
	
// lighting info
	byte		styles[MAXLIGHTMAPS];
	byte		*samples;		// [numstyles*surfsize]

	msurface_t *nextalphasurface;
} msurface_t;

struct
{
	int		fileofs, filelen;
} lump_t;

struct
{
	int			ident;
	int			version;	
	lump_t		lumps[HEADER_LUMPS];
} dheader_t;

struct
{
	vec3		position;
} mvertex_t;

struct
{
    byte	manufacturer;
    byte	version;
    byte	encoding;
    byte	bits_per_pixel;
    int		xmin,ymin,xmax,ymax;
    int		hres,vres;
    byte	palette[48];
    byte	reserved;
    byte	color_planes;
    int		bytes_per_line;
    int		palette_type;
    byte	filler[58];
    byte	data;			// unbounded
} pcx_t;


// 0-2 are axial planes
#define	PLANE_X			0
#define	PLANE_Y			1
#define	PLANE_Z			2

// 3-5 are non-axial planes snapped to the nearest
#define	PLANE_ANYX		3
#define	PLANE_ANYY		4
#define	PLANE_ANYZ		5

// planes (x&~1) and (x&~1)+1 are always opposites

// plane_t structure
// !!! if this is changed, it must be changed in asm_i386.h too !!!
struct
{
	vec3	normal;
	float	dist;
	byte	type;			// for texture axis selection and fast side tests
	byte	signbits;		// signx + signy<<1 + signz<<1
	byte	pad[2];
} mplane_t;

/* ################
ALIAS MODEL
################ */

struct {
	int s, t;
} stvert_t;

struct 
{
	int	index_xyz[3];
	int	index_st[3];
} triangle_t;

struct
{
	byte	v[3];
	byte	lightnormalindex;
} dtrivertx_t;

struct
{
	float		scale[3];	// multiply byte verts by this
	float		translate[3];	// then add this
	dtrivertx_t	verts[1];	// variable sized
} daliasframe_t;

struct
{
	float origin[3];
	float angles[3];
	
	float mins[3];
	float maxs[3];
	
	int framesize,skinwidth,skinheight,num_xyz,num_st,num_tris,num_cverts,num_frames;
	
	stvert_t *st;
	triangle_t *tris;
	daliasframe_t *frames;
	int frame;
	
	float backlerp;
	
	image_t *skin;
} amodel_t;

daliasframe_t *r_thisframe, *r_lastframe;

#__body__
